import { Slots } from "vue";
import { DynamicTableProps } from "../dynamic-table";
import { TableActionType } from "../types/tableAction";
import { TableMethods } from "./useTableMethods";
import { TableState } from "./useTableState";
import { cloneDeep } from "lodash-es";
import { TableColumn } from "../types/column";
import { ShowMap } from "./tableMap";

export type UseTableColumnsContext = {
  state: TableState;
  props: DynamicTableProps;
  methods: TableMethods;
  tableAction?: TableActionType;
  slots: Slots;
};
const groupBy = (objectArray: any[], property: string | number) => {
  return objectArray.reduce(
    (pre: { [x: string]: any[] }, cur: { [x: string]: any }) => {
      const key = cur[property];
      if (!pre[key]) {
        pre[key] = [];
      }
      pre[key].push(cur);
      return pre;
    },
    {},
  );
};
export const useColumns = ({
  state,
  methods,
  props,
  tableAction,
}: UseTableColumnsContext) => {
  const slots = useSlots();
  const innerColumns = ref(props.columns);
  const customSlotArr = ref<any>([]);
  const editArr = ref<any>([]);
  const { getProps } = state;
  editArr.value = props.editColumns && props.editColumns.split(",");
  const eleArr = ref<any>([]);
  customSlotArr.value =
    props?.columnDistype && Object.keys(props?.columnDistype);
  watchEffect(() => {
    eleArr.value = [];
    const innerProps = { ...unref(getProps) };
    let hideColumns = innerProps.hideColumns
      ? innerProps.hideColumns.split(",")
      : [];
    let columns = cloneDeep(
      innerProps!.columns!.filter(
        (n) =>
          n &&
          n.showInTable != false &&
          !hideColumns?.includes(n.key) &&
          n.accessRight >= 2,
      ),
    );
    //表格展示字段
    if (innerProps?.columnDistype) {
      columns.forEach((_) => {
        if (innerProps?.columnDistype[_.key]) {
          _.customSlot = _.key;
          _.showType = ShowMap.get(innerProps?.columnDistype[_.key]);
        }
      });
    }

    if (
      props?.btnsArr &&
      Array.isArray(props?.btnsArr) &&
      props?.btnsArr.some((_) => _.disType == "20")
    ) {
      ///计算默认操作列宽度 TODO设置不生效
      const operateWidthCalculate = props?.btnsArr
        .filter((_) => _.disType == "20")
        .reduce((p, c) => (p += c.name.length * 14), 0);

      columns.push({
        key: "ACTIO",
        title: "操作",
        align: "center",
        fixed: "right",
        rowspan: 1,
        width: `${Math.max(operateWidthCalculate, innerProps.operateColumnWidth)}px`,
        customSlot: "ACTIO",
      } as unknown as TableColumn);
    }
    if (innerProps.editColumns) {
      columns.forEach((_) => {
        if (editArr.value.includes(_.key)) {
          _.editable = true;
          _.customSlot = _.key;
        }
      });
    }
    //排序字段
    if (innerProps?.sortColumns) {
      const sortColumns = innerProps.sortColumns.split(",");
      columns.forEach((_) => {
        if (sortColumns.includes(_.key)) {
          _.sort = "desc";
        }
      });
    }
    // 是否添加序号列
    if (innerProps?.enableIndexRow) {
      columns.unshift({
        key: "INDEX",
        title: "序号",
        width: "60px",
        align: "center",
        rowspan: 1,
        fixed: innerProps?.fixedIndex ? "left" : undefined,
        customSlot: "INDEX",
      } as unknown as TableColumn);
    }
    // 是否添加多选框
    if (innerProps.enableCheckBox) {
      columns.unshift({
        title: "选项",
        width: "55px",
        type: "checkbox",
        fixed: "left",
      } as TableColumn);
    }
    // 是否添加多选框
    if (innerProps.enableRadio) {
      columns.unshift({
        title: "选项",
        width: "55px",
        type: "radio",
        fixed: "left",
      } as TableColumn);
    }
    columns.forEach((_) => {
      _.ellipsisTooltip = true;
      //展示类型

      if (["1", "3", "4", "6", "7", "8", "9", "10"].includes(_.eleType)) {
        eleArr.value.push(_.key);
        _.customSlot = _.key;
      }

      //列宽
      if (innerProps.columnWidth && innerProps.columnWidth[_.key]) {
        _.width = _.width ? _.width : `${innerProps.columnWidth[_.key]}px`;
      }

      // 根据表头title 计算宽度
      if (state.tableData && state.tableData.value.length) {
        const el = state.tableData.value.toSorted((a, b) => {
          return (
            JSON.stringify(a[_.key])?.length - JSON.stringify(b[_.key])?.length
          );
        });
        const contentLength = el ? JSON.stringify(el[0][_.key])?.length : 0;
        const maxWidth =
          Math.max(_.title.length, contentLength) * 15 +
          30 +
          Number(!!_.sort && 10);
        console.log(maxWidth, contentLength, _.title.length, 1111111111);

        _.width = _.width || maxWidth + "px";
      } else {
        _.width = _.width
          ? _.width
          : _.title.length * 15 + 30 + Number(!!_.sort && 10) + "px";
      }

      if (innerProps.columnName && innerProps.columnName[_.key]) {
        _.title = innerProps.columnName[_.key];
      }
    });
    //二级表头
    if (
      innerProps.enableSubHeader &&
      columns.findIndex((_) => _.groupName != null) > -1
    ) {
      const childrensObj = groupBy(cloneDeep(columns), "groupName");
      columns.forEach((_) => {
        if (_.groupName && _.groupName != null && innerProps.enableSubHeader) {
          _.title = _.groupName;
          _.align = "center";
          _.width = `${childrensObj[_.groupName] * 100}px`; ///默认列宽100
          _.children = childrensObj[_.groupName];
          _.children?.sort((a, b) => a.orderId - b.orderId);
        }
      });

      if (JSON.stringify(childrensObj) != "{}") {
        columns = columns.reduce((acc, curr) => {
          const index = acc.findIndex(
            (item) => item.groupName === curr.groupName,
          );
          if (index < 0 || curr.groupName == null) {
            acc.push(curr);
          }
          return acc;
        }, []);
      }
    }
    columns.sort((a, b) => a.orderId - b.orderId);
    if (innerProps.lockColumnCount) {
      columns.forEach((item, index) => {
        if (index < innerProps.lockColumnCount) {
          item.fixed = "left";
        }
      });
    }
    innerColumns.value = [...columns];
    return {
      innerColumns,
    };
  });
  return {
    eleArr,
    innerColumns,
    editArr,
    customSlotArr,
  };
};
